#include "GxDrawing2D.h"
#include "GxWinApp.h"

namespace GxWinGUI
{
	namespace Drawing
	{
		HDC WinDC::GetHandle()
		{
			return handle;
		}

		BitmapDC::BitmapDC()
		{
			handle = CreateCompatibleDC(NULL);
		}
		BitmapDC::~BitmapDC()
		{
			DeleteDC(handle);
		}

		void Bitmap::SetBitmap(HBITMAP bitHandle, Byte * imgptr)
		{
			HGDIOBJ OldBmp = SelectObject(Canvas.GetHandle(),handle);
			DeleteObject(OldBmp);
			if (ScanLine) delete [] ScanLine;
			ScanLine = 0;
			if (!imgptr)
				return;
			if (height)
				ScanLine = new Byte *[height];
			else
				ScanLine = 0;
			int rowWidth = width*4;
			for(int i=0;i<height;i++)
			{
				ScanLine[i] = imgptr+rowWidth*i;
			}
		}

		void Bitmap::CreateDIB(int w, int h)
		{
			BITMAPINFO bitInfo;
			void * imgptr = NULL;
			handle = NULL;
			ScanLine = 0;
			bitInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
			bitInfo.bmiHeader.biWidth=w;
			bitInfo.bmiHeader.biHeight=-h;
			bitInfo.bmiHeader.biPlanes=1;
			bitInfo.bmiHeader.biBitCount=32;
			bitInfo.bmiHeader.biCompression=BI_RGB;
			bitInfo.bmiHeader.biSizeImage=0;
			bitInfo.bmiHeader.biXPelsPerMeter=0;
			bitInfo.bmiHeader.biYPelsPerMeter=0;
			bitInfo.bmiHeader.biClrUsed=0;
			bitInfo.bmiHeader.biClrImportant=0;
			bitInfo.bmiColors[0].rgbBlue=255;
			bitInfo.bmiColors[0].rgbGreen=255;
			bitInfo.bmiColors[0].rgbRed=255;
			bitInfo.bmiColors[0].rgbReserved=255;
			width = w;
			height = h;
			handle = CreateDIBSection(0,&bitInfo,DIB_RGB_COLORS,&imgptr,NULL,0);
			SetBitmap(handle, (Byte*)imgptr);
		}

		Bitmap::Bitmap(int w, int h)
		{
			CreateDIB(w,h);
		}

		Bitmap::Bitmap(const String & fileName)
		{
			HBITMAP	TempBmp=(HBITMAP)LoadImage(NULL,fileName.GetStrPtr(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
			if(TempBmp)
			{
				HDC		TempDC=CreateCompatibleDC(NULL);
				BITMAP	TempRec;

				GetObject(TempBmp,sizeof(BITMAP),&TempRec);
				DeleteObject(SelectObject(TempDC,TempBmp));

				handle=0;
				ScanLine=0;
				width = TempRec.bmWidth;
				height = TempRec.bmHeight;
				CreateDIB(TempRec.bmWidth,TempRec.bmHeight);

				BitBlt(Canvas.GetHandle(),0,0,TempRec.bmWidth,TempRec.bmHeight,TempDC,0,0,SRCCOPY);

				DeleteObject(TempDC);
				DeleteObject(TempBmp);
			}
			else
				throw "failed to load image";
		}

		Bitmap::Bitmap(int rs, HMODULE module)
		{
			if (module == 0)
				module = GetModuleHandle(0);
			HBITMAP	TempBmp=(HBITMAP)LoadImage(module,MAKEINTRESOURCE(rs),IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR);
			if(TempBmp)
			{
				HDC		TempDC=CreateCompatibleDC(NULL);
				BITMAP	TempRec;

				GetObject(TempBmp,sizeof(BITMAP),&TempRec);
				DeleteObject(SelectObject(TempDC,TempBmp));

				handle=0;
				ScanLine=0;
				width = TempRec.bmWidth;
				height = TempRec.bmHeight;
				CreateDIB(TempRec.bmWidth,TempRec.bmHeight);

				BitBlt(Canvas.GetHandle(),0,0,TempRec.bmWidth,TempRec.bmHeight,TempDC,0,0,SRCCOPY);

				DeleteObject(TempDC);
				DeleteObject(TempBmp);
			}
			else
				throw "failed to load image";
		}

		Bitmap::~Bitmap()
		{
			SetBitmap(0,0);
		}

		int Bitmap::GetWidth()
		{
			return width;
		}

		int Bitmap::GetHeight()
		{
			return height;
		}
	}
}